package com.hilinos.gb.gb28181.repository.mysql;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hilinos.gb.gb28181.repository.IDeviceRepository;
import com.hilinos.gb.gb28181.repository.mysql.mapper.IDeviceChannelMapper;
import com.hilinos.gb.gb28181.repository.mysql.mapper.IDeviceMapper;
import com.hilinos.gb.gb28181.repository.mysql.mapper.po.Device;
import com.hilinos.gb.gb28181.repository.mysql.mapper.po.DeviceChannel;
import com.hilinos.hilincommon.utils.AssertUtils;
import com.hilinos.hilincommon.utils.ReturnCode;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

public class MysqlDeviceRepository implements IDeviceRepository {
    private IDeviceChannelMapper iDeviceChannelMapper;

    private IDeviceMapper iDeviceMapper;

    public void setiDeviceChannelMapper(IDeviceChannelMapper iDeviceChannelMapper) {
        this.iDeviceChannelMapper = iDeviceChannelMapper;
    }

    public void setiDeviceMapper(IDeviceMapper iDeviceMapper) {
        this.iDeviceMapper = iDeviceMapper;
    }

    /**
     * 根据设备ID判断设备是否存在
     *
     * @param deviceId 设备ID
     * @return true:存在  false：不存在
     */
    @Override
    public boolean exists(String deviceId) {
        return !ObjectUtils.isEmpty(iDeviceMapper.selectById(deviceId));
    }

    /**
     * 视频设备创建
     *
     * @param deviceVo 设备对象
     * @return true：创建成功  false：创建失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(Device deviceVo) {
        AssertUtils.isNotEmpty(deviceVo.getDeviceId(), ReturnCode.NORMAL_PARAM_LOST_ERROR);
        if (exists(deviceVo.getDeviceId())) {
            iDeviceMapper.updateById(deviceVo);
        } else {
            iDeviceMapper.insert(deviceVo);
        }
        if (!ObjectUtils.isEmpty(deviceVo.getChannelMap())) {
            deviceVo.getChannelMap().forEach((s, deviceChannel) -> {
                if (deviceChannel == null) {
                    return;
                }
                if (!ObjectUtils.isEmpty(deviceChannel.getChannelId())) {
                    if (iDeviceChannelMapper.selectById(deviceChannel.getChannelId()) == null) {
                        iDeviceChannelMapper.insert(deviceChannel);
                    } else {
                        iDeviceChannelMapper.updateById(deviceChannel);
                    }
                }
            });
        }
        return true;
    }

    /**
     * 视频设备更新
     *
     * @param deviceVo 设备对象
     * @return true：更新成功  false：更新失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(Device deviceVo) {
        return create(deviceVo);
    }

    /**
     * 获取设备
     *
     * @param deviceId 设备ID
     * @return Device 设备对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Device queryVideoDevice(String deviceId) {

        Device deviceDb = iDeviceMapper.selectById(deviceId);
        if (deviceDb == null) {
            return null;
        }
        deviceDb.setChannelMap(new HashMap<>());
        QueryWrapper<DeviceChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(DeviceChannel::getDeviceId, deviceId);
        List<DeviceChannel> deviceChannels = iDeviceChannelMapper.selectList(queryWrapper);
        if (!ObjectUtils.isEmpty(deviceChannels)) {
            for (DeviceChannel deviceChannel : deviceChannels) {
                deviceDb.getChannelMap().put(deviceChannel.getChannelId(), deviceChannel);
            }
        }
        return deviceDb;
    }

    @Override
    public List<Device> queryOnlineDevice() {
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(Device::getOnline, Device.STATUS_ONLINE);
        List<Device> deviceList = iDeviceMapper.selectList(queryWrapper);
        if (!ObjectUtils.isEmpty(deviceList)) {
            String[] deviceIds = new String[deviceList.size()];
            for (int i = 0; i < deviceList.size(); i++) {
                Device device = deviceList.get(i);
                deviceIds[i] = device.getDeviceId();
            }
            return queryVideoDeviceList(deviceIds);
        }
        return deviceList;
    }

    /**
     * 获取多个设备
     *
     * @param deviceIds 设备ID数组
     * @return List<Device> 设备对象数组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Device> queryVideoDeviceList(String[] deviceIds) {
        List<Device> deviceDbs = null;
        if (ObjectUtils.isEmpty(deviceIds)) {
            deviceDbs = iDeviceMapper.selectList(new QueryWrapper<>());
        } else {
            deviceDbs = iDeviceMapper.selectBatchIds(Arrays.asList(deviceIds));
        }

        if (ObjectUtils.isEmpty(deviceDbs)) {
            return deviceDbs;
        }

        QueryWrapper<DeviceChannel> queryWrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(deviceIds)) {
            queryWrapper.lambda().in(DeviceChannel::getDeviceId, Arrays.asList(deviceIds));
        }
        List<DeviceChannel> channels = iDeviceChannelMapper.selectList(queryWrapper);
        for (Device deviceDb : deviceDbs) {
            deviceDb.setChannelMap(new HashMap<>());
            for (DeviceChannel channel : channels) {
                if (deviceDb.getDeviceId().equals(channel.getDeviceId())) {
                    deviceDb.getChannelMap().put(channel.getChannelId(), channel);
                }
            }
        }

        return deviceDbs;
    }

    /**
     * 删除设备
     *
     * @param deviceId 设备ID
     * @return true：删除成功  false：删除失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(String deviceId) {
        iDeviceMapper.deleteById(deviceId);
        QueryWrapper<DeviceChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DeviceChannel::getDeviceId, deviceId);
        iDeviceChannelMapper.delete(queryWrapper);
        return true;
    }

    /**
     * 更新设备在线
     *
     * @param deviceIds 设备ID列表
     * @return true：更新成功  false：更新失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean onlines(List<String> deviceIds) {
        if (ObjectUtils.isEmpty(deviceIds)) {
            return true;
        }
        UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(Device::getOnline, "1")
                .in(Device::getDeviceId, deviceIds);
        iDeviceMapper.update(null, updateWrapper);
        return true;
    }

    /**
     * 更新设备离线
     *
     * @param deviceIds 设备ID列表
     * @return true：更新成功  false：更新失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean outlines(List<String> deviceIds) {
        if (ObjectUtils.isEmpty(deviceIds)) {
            return true;
        }
        UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(Device::getOnline, "0")
                .in(Device::getDeviceId, deviceIds);
        iDeviceMapper.update(null, updateWrapper);
        return true;
    }

}
